home *** CD-ROM | disk | FTP | other *** search
- ε Curso de programación orientada a objetos (III)π
-
- µ Teoria y uso de los streamsπ
-
- Otra de esas nuevas cositas "filosóficas" que nos proporciona la POO es el
- envio de mensajes a los objetos (de esto ya hemos hablado), y la pantalla,
- como el disco u otros sistemas de comunicación, son objetos y como tales se
- define una nueva forma de interactuación. Frente a los betustos y a veces
- frustrantes 'δprintf()π' y 'δfread()π' se define ahora 'δcinπ' i 'δcoutπ' (dentro de
- la libreria 'Ωiostream.hπ') que aceptan cualquier tipo de datos predefinidos y
- cualquiera que le podamos definir en un futuro (esto es una cosa fantástica
- que veremos más adelante).
-
- Antes, con 'δprintfπ', por ejemplo, teniamos que decir de que tipo de datos
- se trataba lo que queriamos escribir:
- Γ printf("Mi casa es de color %s", color);π
- Ahora eso ya no hace falta, simplemente llamamos para escribir lo que haya
- que escribir que ya se las arreglará el compilador para saber de que tipo
- son los datos. La sintaxis de C++ para escribir en streams (que así se llaman
- en inglés los ficheros, entre los que se encuentra la pantalla (aquí todo son
- ficheros, como en UNIX!! :) se podria ejemplificar así:
- Γ cout << "Mi casa es de color " << color;π
-
- Por supuesto, se pueden meter más signos δ<<π para seguir escribiendo más cosas
- e incluso para hacer retornos de carros y todo lo que se podia hacer con el C
- tradicional. Al igual que el objeto 'δcoutπ' redirige a la salida estandar, el
- antes mencionado 'δcinπ' hace lo própio con la entrada estandar. Además en otro
- número veremos como todo esto es tambien aplicable a los ficheros de nuestro
- disco duro haciendonos la vida más facil.
-
- µ Métodos inlineπ
-
- Los métodos inline son el sustituto natural de las macros de C. Han de
- definirse e implementarse obligatoriamente detro de la própia definición de la
- clase y no pueden ser estáticos (ya veremos que es ésto). Un ejemplo podria
- ser el siguiente:
-
- Γ class Inlines {π
- Γ private: π
- Γ int status;π
- Γ [...] π
- Γ public: π
- Γ [...] π
- Γ inline int error(void) { return status; }π
- Γ [...]π
- Γ };π
-
- Observa que la definición y el cuerpo del método van unidos y no hay que
- redefinirlo en ningún otro sítio. Esta función de ejemplo, lo único que hace
- es devolver un valor de una variable privada que supuestamente controla los
- errores de la clase; por ello podria resultar un poco lento implementarlo como
- un método normal (porque habria que añadir una llamada a procedimiento y demás).
-
- µ Constructores y destructoresπ
-
- Muchas veces, si programas en Pascal usando TPUs, habrás usado la parte de
- la TPU que se ejecuta siempre que se incluye ésta, para inicializar variables
- o mostrar mensajes, pero tambien otras veces te hubiera podido hacer falta
- hacer lo mismo para acabar y no lo has podido hacer. Los Ωconstructoresπ de C++
- son unos métodos que se ejecutan cada vez que creas una instancia de un objeto
- y que te permiten inicializar variables, pedir memoria, etc. Los Ωdestructoresπ
- son un método que tiene cada clase y que se ejecuta al eliminarse cada objeto
- instanciado.
- Para ver la potencia de los constructores y destructores podemos imaginar
- que queremos crear una clase que maneje una lista de números complejos u otros
- objetos de forma dinámica (pidiendo memoria cada vez que se añade un elemento
- y liberandola cada vez que se elimina uno). Si usaramos los métodos
- tradicionales, tendriamos que pedir memoria explícitamente en cada método,
- usando el paradigma de la OO podemos crear un constructor que cada vez que se
- instancie un objeto, reserve la memoria suficiente para contenerse y luego
- automáticamente se libere esa memoria.
- La definición de los constructores es bastante sencilla: se trata de un
- método que no devuelve nada y que tiene el mismo nombre que la clase que lo
- contiene. De forma similar, el destructor es un método que no devuelve nada y
- tampoco recibe parámetros de entrada y cuyo nombre es el mismo de la clase,
- pero precedido del signo tilde δ~π (ALT+126). Un ejemplo:
-
- Γ class Coche {π
- Γ [...] π
- Γ public: π
- Γ [...] π
- Γ Coche(char *Marca, char *Modelo);π
- Γ ~Coche(); π
- Γ }; π
-
- Γ Coche :: Coche(char *Marca, char *Modelo) {π
- Γ [...] π
- Γ } π
-
- Γ Coche :: ~Coche() { π
- Γ [...] π
- Γ } π
-
- Podemos observar que la definición debe estar en la parte pública ya que si
- no fuese así, el compilador no podria acceder a los métodos Coche y ~Coche.
- Hay que observar tambien, que el destructor ∞NUNCAπ puede llevar parámetros,
- mientras el constructor puede llevarlos o no.
-
- µ La herenciaπ
-
- Como parábola de la realidad, la heréncia es una forma de que los que vienen
- después cojan lo que se ha creado por/para los que habia antes. Imaginemos que
- tenemos una clase "δAvionπ" en la que están definidas una série de abstracciones
- generales de todos los aviones (combustible, altura máxima, peso, etc). Ahora
- queremos hacer una clase "δBombarderoπ" y nos encontramos con el problema de que
- tenemos que reescribir todos los métodos anteriores junto con las variables y
- demás. ¿Como solucionar ésto? Con la herencia. Si de alguna manera pudiesemos
- aprovechar el trabajo realizado con "δAvionπ" y no tenerlo que reescribir para
- "δBombarderoπ" estariamos ganando mucho tiempo y trabajo. Si hacemos que la
- clase "δBombarderoπ" φHEREDEπ de "δAvionπ", solucionamos el problema; podriamos
- hacerlo así:
-
- Γ class Avion {π
- Γ private: π
- Γ int combustible;π
- Γ int velocidad; π
- Γ public: π
- Γ void acelera(int v);π
- Γ Avion(); π
- Γ ~Avion(); π
- Γ }; π
-
- Γ class Bombardero : public Avion { π
- Γ private: π
- Γ int num_bombas; π
- Γ public: π
- Γ inline int lanza(void) { return --num_bombas; }π
- Γ Bombardero(); π
- Γ ~Bombardero(); π
- Γ }; π
-
- La primera clase ("δAvionπ") no tiene nada nuevo, pero la clase "δBombarderoπ"
- ya va teniendo en la primera línea cosas "extrañas". Con ese tipo de definición,
- lo que queremos decirle al compilador es: "Ωdefineme una clase llamada π
- ΩBombardero que herede públicamente (lo que era publico que lo siga siendo) deπ
- Ωla clase Avion todos sus atributosπ". Así, en la clase "δBombarderoπ", no tendremos
- como privada sólo 1 variable ("δnum_bombasπ"), sino que tendremos 3, las 2 de
- "δAvionπ" y la própia. De la misma forma, no tendremos como pública sólo el
- método "δlanza()π" y el constructor+destructor, sino que heredamos el método
- "δacelera()π" de la clase padre.
-
- µ Uso de directivas del compiladorπ
-
- No sólo para la POO es necesario usar bien las directivas que te ofrece el
- compilador, es una forma de hacer más robusto y legible nuestro código. Las
- que se usan principalmente suelen ser δ#ifdefπ, δ#ifndefπ, δ#endifπ e δ#includeπ.
- No hay mucho que decir acerca de todas ellas, pues su uso está claro, pero es
- muy interesante que comienzes a meterlas por tus clases para que el compilador
- no te de grandes errores. Un uso frequente y que recomiendo es el siguiente:
-
- Γ // Fichero "claseA.hpp"π
-
- Γ #ifndef __CLASE_A__ π
- Γ #define __CLASE_A__ π
-
- Γ class A { π
- Γ [...] π
- Γ }; π
-
- Γ #endif π
-
- µ Reglas prácticas para compilarπ
-
- Si estas muy habituado a usar C sin crearte ficheros de proyecto, puede que
- caigas muchas veces (hasta que te acostumbres) en el error de incluir tanto la
- definición como la implementación de cada una de las clases usadas. Si lo haces
- así e incluyes una misma clase en 2 lugares distintos, el compilador te dará
- un error de duplicación en la definición.
- Para evitar todos los errores de este tipo, lo mejor es tener claro donde
- debes poner las directivas del compilador y usar los ficheros de proyecto.
- Para usarlos sólo tienes que crear uno con el entorno que te proporciona el
- compilador e insertar allí todos los ficheros auxiliares que uses. Además,
- sólo deberás incluir los ficheros de definición de cada clase usada y nunca
- la implementación de éstas.
- Ya hay suficiente por éste número, en el próximo intentaremos ver nuestros
- primeros programas compilables, pero hasta entonces es muy recomendable que
- vayas investigando por tu cuenta (hay muchas clases interesantes en los
- compiladores comerciales). Hasta la vista.
-
-